<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>展示学生信息</title>
    <link rel="icon" th:href="@{/favicon.png}" type="image/png"/>
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <style>
        .container {
            font-family: Arial, sans-serif;
            padding: 20px;
            width: 100%;
            max-width: 1200px;
            margin: 0 auto;
        }

        .filter-container {
            display: flex;
            flex-wrap: wrap;
            margin-bottom: 20px;
        }

        .filter-group {
            margin-right: 20px;
            margin-bottom: 10px;
            display: flex;
            align-items: center;
        }

        .filter-label {
            margin-right: 5px;
            font-weight: bold;
        }

        .filter-select {
            padding: 5px 10px;
            border-radius: 4px;
            border: 1px solid #ccc;
            font-size: 14px;
        }

        .search-button {
            padding: 10px 20px;
            background-color: #1890ff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
            margin-left: 10px;
        }

        .search-button:hover {
            background-color: #0c7cd5;
        }

        .table-container {
            width: 100%;
            overflow-x: auto;
        }

        .table-header {
            background-color: #f2f2f2;
        }

        .table-row {
            border-bottom: 1px solid #ddd;
        }

        .table-row:hover {
            background-color: #f9f9f9;
        }

        .pagination-control {
            display: flex;
            align-items: center;
            margin-top: 20px;
        }

        .pagination-info {
            margin-right: 20px;
        }

        .pagination-button {
            padding: 5px 10px;
            background-color: #f5f5f5;
            border: 1px solid #ccc;
            border-radius: 4px;
            cursor: pointer;
            margin: 0 5px;
        }

        .pagination-button:disabled {
            background-color: #e0e0e0;
            cursor: not-allowed;
        }

        .page-size-select {
            padding: 5px 10px;
            border-radius: 4px;
            border: 1px solid #ccc;
            margin-left: 10px;
        }

        .drawer {
            position: fixed;
            top: 0;
            right: -500px;
            width: 500px;
            height: 100%;
            background-color: white;
            box-shadow: -2px 0 8px rgba(0, 0, 0, 0.15);
            transition: right 0.3s ease;
            z-index: 1000;
            padding: 20px;
            box-sizing: border-box;
        }

        .drawer.open {
            right: 0;
        }

        .drawer-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 20px;
            border-bottom: 1px solid #f0f0f0;
            padding-bottom: 10px;
        }

        .drawer-title {
            font-size: 18px;
            font-weight: bold;
            margin: 0;
        }

        .drawer-close {
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            color: #999;
        }

        .drawer-close:hover {
            color: #333;
        }

        .drawer-table {
            width: 100%;
            border-collapse: collapse;
        }

        .drawer-th,
        .drawer-td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }

        .drawer-th {
            background-color: #f2f2f2;
        }

        .drawer-backdrop {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            z-index: 999;
            display: none;
        }

        .drawer-backdrop.open {
            display: block;
        }

        /* 表格样式 */
        .table {
            width: 100%;
            border-collapse: collapse;
        }

        .th,
        .td {
            border: 1px solid #ddd;
            padding: 8px;
            text-align: left;
        }

        .th {
            background-color: #f2f2f2;
        }

        .button {
            padding: 5px 10px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            margin: 0 2px;
        }

        .button:hover {
            background-color: #45a049;
        }

        /* 添加人数统计卡片 */
        .stats-container {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
            gap: 1.5rem;
            margin: 2rem 0;
        }

        .stat-card {
            background: linear-gradient(145deg, #f5f7fa, #e4e9f0);
            border-radius: 8px;
            padding: 1.5rem;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            transition: transform 0.3s ease;
            border: 1px solid #e0e6ed;
        }

        .stat-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1);
        }

        .stat-header {
            display: flex;
            align-items: center;
            margin-bottom: 1rem;
        }

        .stat-icon {
            width: 40px;
            height: 40px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            margin-right: 1rem;
            background-color: rgba(66, 133, 244, 0.2);
            border: 1px solid rgba(66, 133, 244, 0.3);
        }

        .stat-title {
            color: #333333;
            font-size: 0.9rem;
        }

        .stat-value {
            font-size: 2.2rem;
            font-weight: bold;
            text-shadow: 0 0 5px rgba(66, 133, 244, 0.2);
            color: #1a1a1a;
        }
    </style>
</head>
<body>
<div id="app" class="container">
    <!-- 搜索过滤区域 -->
    <div class="filter-container">
        <div class="filter-group">
            <label for="type" class="filter-label">类型：</label>
            <select id="type" v-model="type" class="filter-select">
                <option value="UNDERGRAD">本科生</option>
                <option value="GRADUATE">研究生</option>
            </select>
        </div>
        <div class="filter-group">
            <label for="sortField" class="filter-label">排序方案：</label>
            <select id="sortField" v-model="sortField" class="filter-select">
                <option value="student_id">学号</option>
                <option value="name">姓名</option>
                <option value="age">年龄</option>
                <option value="classNum">班级</option>
            </select>
            <select id="order" v-model="sortOrder" class="filter-select">
                <option value="asc">升序</option>
                <option value="desc">降序</option>
            </select>
        </div>
        <button @click="loadStudents" class="search-button">展示</button>
    </div>

    <!-- 学生表格 -->
    <div class="table-container">
        <table class="table">
            <thead class="table-header">
            <tr class="table-row">
                <th class="th">学号</th>
                <th class="th">姓名</th>
                <th class="th">性别</th>
                <th class="th">年龄</th>
                <th class="th">类型</th>
                <th class="th">班级</th>
                <th class="th">地址</th>
                <th class="th">就学信息</th>
                <th class="th">成绩</th>
            </tr>
            </thead>

            <tbody>
            <tr v-for="student in students" :key="student.studentId" class="table-row">
                <td class="td">{{ student.studentId }}</td>
                <td class="td">{{ student.name }}</td>
                <td class="td">{{ student.age }}</td>
                <td class="td">{{ student.gender === 'MALE' ? '男' : '女' }}</td>
                <td class="td">{{ student.type === 'UNDERGRAD' ? '本科生' : '研究生' }}</td>
                <td class="td">{{ student.classNum }}</td>
                <td class="td">{{ student.province }}{{ student.city }}{{ student.street }}{{student.doorNumber}}</td>
                <td class="td">
                    <span v-if="student.type === 'UNDERGRAD'">{{ student.major }}</span>
                    <div v-else>
                        <div>导师：{{ student.supervisor }}</div>
                        <div>方向：{{ student.researchFiled }}</div>
                    </div>
                </td>
                <td class="td">
                    <button class="button" @click="loadStudentScores(student.scores)">查看成绩</button>
                </td>
            </tr>
            </tbody>
        </table>
    </div>

    <!-- 分页控制 -->
    <div class="pagination-control">
        <span class="pagination-info">第 {{ currentPage }} 页<br>共 {{ totalPages }} 页</span>
        <button class="pagination-button" @click="prevPage" :disabled="currentPage === 1">上一页</button>
        <button class="pagination-button" @click="nextPage" :disabled="currentPage >= totalPages">下一页</button>
        <select class="page-size-select" v-model="pageSize" @change="changePageSize">
            <option>5</option>
            <option>10</option>
            <option>20</option>
        </select>
    </div>

    <!--学生人数统计-->
    <div class="stats-container" v-if="currentView === 'list'">
        <div class="stat-card">
            <div class="stat-header">
                <div class="stat-icon">👥</div>
                <div>
                    <div class="stat-title">总学生数</div>
                    <div class="stat-value">{{ stats.total || 0 }}</div>
                </div>
            </div>
            <div class="stat-sub">实时更新数据</div>
        </div>

        <div class="stat-card">
            <div class="stat-header">
                <div class="stat-icon">🎓</div>
                <div>
                    <div class="stat-title">本科生</div>
                    <div class="stat-value">{{ stats.undergradCount || 0 }}</div>
                </div>
            </div>
            <div class="stat-sub">占比 {{ undergradPercent }}%</div>
        </div>

        <div class="stat-card">
            <div class="stat-header">
                <div class="stat-icon">📚</div>
                <div>
                    <div class="stat-title">研究生</div>
                    <div class="stat-value">{{ stats.graduateCount || 0 }}</div>
                </div>
            </div>
            <div class="stat-sub">占比 {{ graduatePercent }}%</div>
        </div>
    </div>

    <!-- 抽屉显示学生成绩表格 -->
    <div class="drawer" :class="{ open: isDrawerOpen }">
        <div class="drawer-header">
            <h3 class="drawer-title">成绩信息</h3>
            <button class="drawer-close" @click="closeDrawer">×</button>
        </div>
        <table class="drawer-table">
            <thead>
            <tr class="drawer-row">
                <th class="drawer-th">课程名</th>
                <th class="drawer-th">分数</th>
            </tr>
            </thead>
            <tbody>
            <tr v-for="(score, course) in grades" :key="course" class="drawer-row">
                <td class="drawer-td">{{ course }}</td>
                <td class="drawer-td">{{ score }}</td>
            </tr>
            </tbody>
        </table>
    </div>

    <div class="drawer-backdrop" :class="{ open: isDrawerOpen }"></div>
</div>

<script type="module">
    const {createApp} = Vue;

    createApp({
        data() {
            return {
                students: [],
                currentPage: 1,
                pageSize: 10,
                totalPages: 1,
                type: 'GRADUATE',
                sortField: 'student_id',
                sortOrder: 'asc',
                isDrawerOpen: false,
                grades: {},
                currentView: 'list',
                stats: {
                    total: 0,
                    undergradCount: 0,
                    graduateCount: 0
                }
            }
        },
        created() {
            this.loadStudents();
            this.fetchStats()
        },
        computed: {
            undergradPercent() {
                return this.calculatePercentage(this.stats.undergradCount)
            },
            graduatePercent() {
                return this.calculatePercentage(this.stats.graduateCount)
            }
        },
        methods: {
            async loadStudents() {
                try {
                    const params= {
                        pageNum: this.currentPage,
                        pageSize: this.pageSize,
                        type: this.type,
                        sort: this.sortField,
                        order: this.sortOrder
                    }

                    const response = await axios.get('http://localhost:8080/api/students', { params });
                    this.students = response.data.data.list;
                    this.totalPages = Math.ceil(response.data.data.total / params.pageSize);
                } catch (error) {
                    console.error('Error loading students:', error);
                }
            },
            prevPage() {
                if (this.currentPage > 1) {
                    this.currentPage--;
                    this.loadStudents();
                }
            },
            nextPage() {
                if (this.currentPage < this.totalPages) {
                    this.currentPage++;
                    this.loadStudents();
                }
            },
            changePageSize(){
                this.currentPage = 1;
                this.loadStudents();
            },
            loadStudentScores(scores) {
                this.isDrawerOpen = true;
                this.grades = scores;
            },
            async closeDrawer(){
                this.isDrawerOpen = false;
            },
            async fetchStats() {
                try {
                    const response = await axios.get('/api/students/stats')
                    this.stats = response.data.data
                } catch (error) {
                    console.error('统计信息获取失败:', error)
                }
            },
            calculatePercentage(value) {
                if (!this.stats.total) return 0
                return ((value / this.stats.total) * 100).toFixed(1)
            }
        }

    }).mount('#app')
</script>
</body>
</html>